//
//  KYServerClient.m
//  KYServerClient
//
//  Created by mrj on 16/7/1.
//  Copyright © 2016年 ikaiyong. All rights reserved.
//

#import "KYServerClient.h"
#import <netinet/in.h>

@interface KYServerClient ()

@end
@implementation KYServerClient
#pragma mark - 初始化
-(instancetype)init
{
    if (self = [super init]) {
        
        self.sessionManager = [AFHTTPSessionManager manager];
        
        
        //客服端请求验证 重写 setSessionDidReceiveAuthenticationChallengeBlock 方法
        __weak typeof(self)weakSelf = self;
        [self.sessionManager setSessionDidReceiveAuthenticationChallengeBlock:^NSURLSessionAuthChallengeDisposition(NSURLSession*session, NSURLAuthenticationChallenge *challenge, NSURLCredential *__autoreleasing*_credential) {
            NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;
            __autoreleasing NSURLCredential *credential =nil;
            if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
                if([weakSelf.sessionManager.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host]) {
                    credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
                    if(credential) {
                        disposition =NSURLSessionAuthChallengeUseCredential;
                    } else {
                        disposition =NSURLSessionAuthChallengePerformDefaultHandling;
                    }
                } else {
                    disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;
                }
            } else {
                // client authentication
                SecIdentityRef identity = NULL;
                SecTrustRef trust = NULL;
                NSString *p12 = [[NSBundle mainBundle] pathForResource:@"client"ofType:@"p12"];
                NSFileManager *fileManager =[NSFileManager defaultManager];
                
                if(![fileManager fileExistsAtPath:p12])
                {
                    NSLog(@"client.p12:not exist");
                }
                else
                {
                    NSData *PKCS12Data = [NSData dataWithContentsOfFile:p12];
                    
                    if ([[weakSelf class]extractIdentity:&identity andTrust:&trust fromPKCS12Data:PKCS12Data])
                    {
                        SecCertificateRef certificate = NULL;
                        SecIdentityCopyCertificate(identity, &certificate);
                        const void*certs[] = {certificate};
                        CFArrayRef certArray =CFArrayCreate(kCFAllocatorDefault, certs,1,NULL);
                        credential =[NSURLCredential credentialWithIdentity:identity certificates:(__bridge  NSArray*)certArray persistence:NSURLCredentialPersistencePermanent];
                        disposition =NSURLSessionAuthChallengeUseCredential;
                    }
                }
            }
            *_credential = credential;
            return disposition;
        }];
        
        
        
        
        NSString *certFilePath = [[NSBundle mainBundle] pathForResource:@"ca" ofType:@"der"];
        NSData *certData = [NSData dataWithContentsOfFile:certFilePath];
        NSSet *certSet = [NSSet setWithObject:certData];
        AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate withPinnedCertificates:certSet];
        
        self.sessionManager.securityPolicy = policy;
        self.sessionManager.requestSerializer = [AFHTTPRequestSerializer serializer];
        self.sessionManager.responseSerializer = [AFHTTPResponseSerializer serializer];
        
        self.sessionManager.responseSerializer.acceptableContentTypes =  [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/plain", @"text/html",nil];
        //关闭缓存避免干扰测试r
        self.sessionManager.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
        //是否接受无效的证书
        self.sessionManager.securityPolicy.allowInvalidCertificates= YES;
        //是否匹配域名
        self.sessionManager.securityPolicy.validatesDomainName = YES;
    }
    return self;
}

#pragma mark - Mutual Authentication --

+(BOOL)extractIdentity:(SecIdentityRef*)outIdentity andTrust:(SecTrustRef *)outTrust fromPKCS12Data:(NSData *)inPKCS12Data {
    OSStatus securityError = errSecSuccess;
    //client certificate password
    NSDictionary*optionsDictionary = [NSDictionary dictionaryWithObject:@"shinowyf2"
                                                                 forKey:(__bridge id)kSecImportExportPassphrase];
    
    CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
    securityError = SecPKCS12Import((__bridge CFDataRef)inPKCS12Data,(__bridge CFDictionaryRef)optionsDictionary,&items);
    
    if(securityError == 0) {
        CFDictionaryRef myIdentityAndTrust =CFArrayGetValueAtIndex(items,0);
        const void*tempIdentity =NULL;
        tempIdentity= CFDictionaryGetValue (myIdentityAndTrust,kSecImportItemIdentity);
        *outIdentity = (SecIdentityRef)tempIdentity;
        const void*tempTrust =NULL;
        tempTrust = CFDictionaryGetValue(myIdentityAndTrust,kSecImportItemTrust);
        *outTrust = (SecTrustRef)tempTrust;
    } else {
        NSLog(@"Failedwith error code %d",(int)securityError);
        return NO;
    }
    return YES;
}

#pragma mark - 服务器客户端单例
+ (KYServerClient *)shareServerClient
{
    static KYServerClient *serverClient = nil;
    static dispatch_once_t pre;
    dispatch_once(&pre, ^{
        
        serverClient = [[KYServerClient alloc]init];
        
    });
    return serverClient;
}
#pragma mark - 发送请求
- (void)sendRequestMethod:(IHealthServerRequestMethod)method
                      URL:(NSString*)URLString
               parameters:(id)parameters
             pertreatment:(void(^)(void))pertreatment
                 progress:(void (^)(NSProgress *downloadProgress))downloadProgress
                  success:(void (^)(NSURLSessionDataTask *task, id  responseObject))success
                  failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
{
    
    
    if ([self isReachableNetwork] == NO) {
        
        [KY_HUB_VIEW hideHubView];
        [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
        
        
        [KY_HUB_VIEW showHubViewTitle:@"网络连接失败,请检查网络连接情况" defaultTimeInView:[UIApplication sharedApplication].delegate.window];
        [self.sessionManager.operationQueue cancelAllOperations];
        
        return;
    }
    if (pertreatment) {
        
        pertreatment();
    }
    
    //超时设置
    self.sessionManager.requestSerializer.timeoutInterval = 30.f;
    self.sessionManager.responseSerializer = [AFHTTPResponseSerializer serializer];
    
    
    if (method == IHealthServerRequestMethodGET) {
        
        [self.sessionManager GET:URLString parameters:parameters progress:downloadProgress success:success failure:failure];
        
    }
    else if (method == IHealthServerRequestMethodPOST){
        
        [self.sessionManager POST:URLString parameters:parameters progress:downloadProgress success:success failure:failure];
    }
}


- ( NSURLSessionDataTask *)sendRequestPOST:(NSString *)URLString
                              pertreatment:(void(^)(void))pertreatment
                                parameters:( id)parameters
                 constructingBodyWithBlock:( void (^)(id <AFMultipartFormData> formData))block
                                  progress:( void (^)(NSProgress *uploadProgress))uploadProgress
                                   success:( void (^)(NSURLSessionDataTask *task, id  responseObject))success
                                   failure:( void (^)(NSURLSessionDataTask *  task, NSError *error))failure
{
    
    if (pertreatment) {
        
        pertreatment();
    }
    
    NSURLSessionDataTask *task = [self.sessionManager POST:URLString parameters:parameters constructingBodyWithBlock:block progress:uploadProgress success:success failure:failure];
    [task  resume];
    return task;
    
}

#pragma mark - 判断网络是否连接
- (BOOL)isReachableNetwork{
    
    struct sockaddr_in zeroAddress;
    bzero(&zeroAddress, sizeof(zeroAddress));
    zeroAddress.sin_len = sizeof(zeroAddress);
    zeroAddress.sin_family = AF_INET;
    
    
    SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
    SCNetworkReachabilityFlags flags;
    
    BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
    CFRelease(defaultRouteReachability);
    
    if (!didRetrieveFlags)
    {
        
        return NO;
    }
    BOOL isReachable = ((flags & kSCNetworkFlagsReachable) != 0);
    BOOL needsConnection = ((flags & kSCNetworkFlagsConnectionRequired) != 0);
    return (isReachable && !needsConnection) ? YES : NO;
}
#pragma mark -------------------------调用------------------------
-(void) sendPostWithURL:(NSString*)url
             parameters:(NSDictionary*)parameters
                toModel:(JSONModel *)model
            showHubName:(HubTipsName)tipsName
           onCompletion:(HttpReuqestSucceedBlock) completionBlock
                onError:(HttpRequestFailedBlock) errorBlock
{
    if (url){
        NSLog(@"url = %@",url);
        [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
        
        if(tipsName == HubTipsShow){
            
            
            [KY_HUB_VIEW showHubViewIndeterminateProgressTitle:@"正在加载" inView:[CommonTool getCurrentVC].view];
            
        }else if(tipsName == HubTipsShowUpload){
            
            [KY_HUB_VIEW showHubViewIndeterminateProgressTitle:@"上传中..." inView:[CommonTool getCurrentVC].view];
            
        }else if (tipsName == HubTipsShowSave){//@"账单查验中，请稍候..."
            
            [KY_HUB_VIEW showHubViewIndeterminateProgressTitle:@"保存中..." inView:[CommonTool getCurrentVC].view];
            
        }else if (tipsName == HubTipsShowLogin){//@"账单查验中，请稍候..."
            
            [KY_HUB_VIEW showHubViewIndeterminateProgressTitle:@"登录中..." inView:[CommonTool getCurrentVC].view];
            
        }else if(tipsName == HubTipsHidden){
            
        }
        
        __block JSONModel *amodel = model;
        
        [self sendRequestMethod:IHealthServerRequestMethodPOST
                            URL:url
                     parameters:parameters
                   pertreatment:^{
                       //                                if (pertreatment) {
                       //                                    pertreatment();
                       //                                }
                       
                   } progress:^(NSProgress *downloadProgress) {
                   } success:^(NSURLSessionDataTask *task, id responseObject) {
                       
                       [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
                       
                       if(tipsName != HubTipsHidden){
                           [KY_HUB_VIEW hideHubView];
                       }
                       
                       NSError *error = nil;
                       
                       NSDictionary *resultDic = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:&error];
                       
                       NSString *ss = [[NSString alloc]initWithData:responseObject encoding:NSUTF8StringEncoding];
                       
                       NSLog(@"url:%@ \n 返回结果： %@",url,ss);
                       
                       if (error) {
                           
                           [error localizedDescription];
                       }
                       
                       if ([resultDic[@"status"] intValue] == 0){
                           if (resultDic[@"errMsg"] && ![@"" isEqualToString:resultDic[@"errMsg"]] && ![resultDic[@"errMsg"] isKindOfClass:[NSNull class]]) {
                               
                               NSLog(@"error : %@",resultDic[@"errMsg"]);
                               
                               [KY_HUB_VIEW showTips:resultDic[@"errMsg"]];
                               
                           }
                           completionBlock(nil);
                           
                       }else{
                           
                           if (model == nil) {
                               
                               completionBlock(resultDic);
                               
                           }else {
                               
                               amodel = [[[model class] alloc] initWithDictionary:resultDic error:&error];
                               completionBlock(amodel);
                               
                           }
                           
                           
                       }
                       
                   } failure:^(NSURLSessionDataTask *task, NSError *error) {
                       [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
                       if(tipsName != HubTipsHidden){
                           [KY_HUB_VIEW hideHubView];
                       }
                       
                       [KY_HUB_VIEW showTips:@"请求服务器异常"];
                       
                       if (errorBlock) {
                           
                           errorBlock(error);
                       }
                   }];
    }
    
}
/**
 *  上传文件
 *
 *  @param url             地址
 *  @param parameters      头信息
 *  @param files           文件信息
 *  @param model           返回model（nil返回字典）
 *  @param completionBlock 成功块
 *  @param errorBlock      失败块
 */
- (void)uploadFileURL:(NSString *)url
           parameters:(NSDictionary*)parameters
                files:(NSDictionary *)files
              toModel:(JSONModel *)model
            filesType:(FileType)filesType
         onCompletion:(HttpReuqestSucceedBlock) completionBlock
              onError:(HttpRequestFailedBlock) errorBlock{
    
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    
    [KY_HUB_VIEW showHubViewIndeterminateProgressTitle:@"上传中..." inView:[CommonTool getCurrentVC].view];
    
    __block JSONModel *amodel = model;
    
    [KY_SERVER_CLIENT sendRequestPOST:url
                       pertreatment:^{ }
                         parameters:parameters
          constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
              
              NSArray *arr = files[@"Files"];
              for (int i = 0; i<arr.count; i++) {
                  
                  NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
                  formatter.dateFormat = @"yyyyMMddHHmmss";
                  NSString *str = [formatter stringFromDate:[NSDate date]];
                  NSString *fileName = @"";
                  
                  
                  NSData *data;
                  
                  if (UIImagePNGRepresentation([arr objectAtIndex:i]) == nil) {
                      
                      data = UIImageJPEGRepresentation([arr objectAtIndex:i], 0.5);
                      
                      fileName = [NSString stringWithFormat:@"%@.jpg", str];
                      [formData appendPartWithFileData:data name:files[@"Name"] fileName:fileName mimeType:@"image/jpeg"];
                      
                  } else {
                      
                      data = UIImagePNGRepresentation([arr objectAtIndex:i]);
                      
                      fileName = [NSString stringWithFormat:@"%@.png", str];
                      [formData appendPartWithFileData:data name:files[@"Name"] fileName:fileName mimeType:@"image/png"];
                      
                  }
                  
              }
              
          } progress:^(NSProgress *uploadProgress) {
              
              
              
          } success:^(NSURLSessionDataTask *task, id responseObject) {
              [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
              [KY_HUB_VIEW hideHubView];
              
              
              if (completionBlock) {
                  
                  [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
                  NSError *error = nil;
                  NSDictionary *resultDic = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:&error];
                  
                  if (error) {
                      
                      [error localizedDescription];
                  }
                  
                  if ([resultDic[@"status"] intValue] == 0){
                      
                      if (resultDic[@"errMsg"] && ![@"" isEqualToString:resultDic[@"errMsg"]] && ![resultDic[@"errMsg"] isKindOfClass:[NSNull class]]) {
                          NSLog(@"error : %@",resultDic[@"errMsg"]);
                          [KY_HUB_VIEW showTips:resultDic[@"errMsg"]];
                          
                      }
                      completionBlock(nil);
                      
                  }else{
                      
                      if (model == nil) {
                          
                          completionBlock(resultDic);
                          
                      }else {
                          
                          amodel = [[[model class] alloc] initWithDictionary:resultDic error:&error];
                          completionBlock(amodel);
                          
                      }
                      
                      
                  }
              }
          } failure:^(NSURLSessionDataTask *task, NSError *error) {
              
              [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
              [KY_HUB_VIEW hideHubView];
              
              if (errorBlock) {
                  
                  errorBlock(error);
              }
              
          }];
}

- (void)uploadFileURL:(NSString *)url
           parameters:(NSDictionary*)parameters
              fileArr:(NSMutableArray *)fileArr
              toModel:(JSONModel *)model
            filesType:(FileType)filesType
         onCompletion:(HttpReuqestSucceedBlock) completionBlock
              onError:(HttpRequestFailedBlock) errorBlock {
    
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    __block JSONModel *amodel = model;
    
    [KY_SERVER_CLIENT sendRequestPOST:url
                       pertreatment:^{ }
                         parameters:parameters
          constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
              
              
              for (int i = 0; i < fileArr.count ; i ++) {
                  for (int j = 0; j < [fileArr[i] count]; j ++) {
                      
                      TLog(@"%d==%d",i,j);
                      NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
                      formatter.dateFormat = @"yyyyMMddHHmmss";
                      NSString *str = [formatter stringFromDate:[NSDate date]];
                      NSString *fileName = [NSString stringWithFormat:@"%@.png", str];
                      
                      UIImage *image = fileArr[i][j];
                      NSData* imageData = UIImageJPEGRepresentation(image, 0.5);
                      [formData appendPartWithFileData:imageData name:[NSString stringWithFormat:@"zls[%d].imgs",i] fileName:fileName mimeType: @"image/png"];
                  }
              }
              
          } progress:^(NSProgress *uploadProgress) {
              
              
              
          } success:^(NSURLSessionDataTask *task, id responseObject) {
              [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
              
              
              if (completionBlock) {
                  
                  NSError* err = nil;
                  
                  NSDictionary *resultDic = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:nil];
                  
                  if (model == nil) {
                      
                      completionBlock(resultDic);
                      
                  }else {
                      amodel = [[[model class] alloc] initWithDictionary:resultDic error:&err];
                      
                      completionBlock(amodel);
                      
                  }
              }
          } failure:^(NSURLSessionDataTask *task, NSError *error) {
              if (error) {
                  [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
                  
              }
              if (errorBlock) {
                  
                  errorBlock(error);
              }
              
          }];
    
    
    
}






/**
 下载图片
 */
- (NSURL*)getDownloadImageById:(NSString*)imageId isThumb:(NSString*)isThumb//是否缩略图：（1-是，0-否），不是图片为0
{
    NSDictionary *parmaetrers = [NSDictionary dictionaryWithObjectsAndKeys:imageId,@"fileId",isThumb,@"isThumb", nil];
    NSString *path = [KY_SERVER_CLIENT getDownloadFileURL:SERVER_CONFIGURE.downloadFile parameters:parmaetrers];
    NSURL *headImageUrl = [NSURL URLWithString:path];
    return headImageUrl;
}
- (NSString *)getDownloadFileURL:(NSString *)url
                      parameters:(NSDictionary*)parameters{
    
    NSMutableString *str = [[NSMutableString alloc] initWithString:url];
    [str appendString:@"?"];
    for (NSString *key in parameters) {
        
        
        NSString *value = [NSString urlEncode:parameters[key]];
        
        [str appendString:key];
        [str appendString:@"="];
        [str appendString:value];
        [str appendString:@"&"];
        
    }
    
    [str appendString:[NSString stringWithFormat:@"typeId=%@",[NSString urlEncode:TYPEID]]];
    //FIXME:-YT 修改这
    
//    [str appendString:[NSString stringWithFormat:@"id=%@",[NSString urlEncode:LOGIN_BEAN.loginUserBean.userId]];
    
    return str;
}
@end
